import 'dart:io';
import 'dart:typed_data';
import 'package:get/get.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:video_compress/video_compress.dart';
import 'package:path_provider/path_provider.dart';
import 'package:vischat/core/utils/app_toast.dart';
import 'package:vischat/generated/route_table.dart';

class MediaPickerController extends GetxController {
  late final int _maxSelection;

  final RxList<AssetEntity> _allMedia = <AssetEntity>[].obs;
  final RxList<AssetEntity> _selectedMedia = <AssetEntity>[].obs;
  final RxString _currentAlbum = '所有资源'.obs;
  final RxList<AssetPathEntity> _albums = <AssetPathEntity>[].obs;
  final RxBool _isLoading = false.obs;

  List<AssetEntity> get allMedia => _allMedia;
  List<AssetEntity> get selectedMedia => _selectedMedia;
  String get currentAlbum => _currentAlbum.value;
  List<AssetPathEntity> get albums => _albums;
  bool get isLoading => _isLoading.value;

  @override
  void onInit() {
    super.onInit();
    _maxSelection = Get.arguments['maxSelection'];
    _requestPermission();
  }

  Future<void> switchAlbum(AssetPathEntity album) async {
    await _loadMedia(album: album);
  }

  void selectAsset(bool val, AssetEntity asset) {
    if (val && _selectedMedia.length >= _maxSelection) {
      AppToast.showToast('assets.max'.trParams({"max": '$_maxSelection'}));
    } else {
      _toggleSelect(asset);
    }
  }

  void _toggleSelect(AssetEntity asset) {
    if (_selectedMedia.contains(asset)) {
      _selectedMedia.remove(asset);
    } else {
      _selectedMedia.insert(0, asset);
    }
  }

  Future<File?> getThumbnail(
    AssetEntity asset, {
    int width = 200,
    int height = 200,
  }) async {
    if (asset.type == AssetType.video) {
      final file = await asset.file;
      if (file != null) {
        final thumbnail = await VideoCompress.getFileThumbnail(
          file.path,
          quality: 50,
          position: 0,
        );
        return thumbnail;
      }
    }
    return await asset.thumbnailDataWithSize(ThumbnailSize(width, height)).then(
      (data) {
        if (data != null) {
          return _writeToFile(data);
        }
        return null;
      },
    );
  }

  Future<void> previewMedia(AssetEntity asset) async {
    final initialIndex = _allMedia.indexOf(asset);
    Get.toNamed(RouteTable.MEDIA_PREVIEW, arguments: {
      'mediaList': _allMedia,
      'index': initialIndex
    });
  }

  Future<void> _requestPermission() async {
    _isLoading.value = true;

    final PermissionState state = await PhotoManager.requestPermissionExtend();
    if (state.isAuth) {
      await _loadAlbums();
      await _loadMedia();
    } else {
      PhotoManager.openSetting();
    }

    _isLoading.value = false;
  }

  Future<void> _loadAlbums() async {
    _albums.value = await PhotoManager.getAssetPathList(
      type: RequestType.common,
      filterOption: FilterOptionGroup(
        videoOption: FilterOption(
          durationConstraint: DurationConstraint(min: Duration(seconds: 1)),
        ),
      ),
    );
  }

  Future<void> _loadMedia({AssetPathEntity? album}) async {
    _isLoading.value = true;

    final AssetPathEntity selectedAlbum = album ?? _albums.first;
    _currentAlbum.value = selectedAlbum.name;

    _allMedia.value = await selectedAlbum.getAssetListRange(
      start: 0,
      end: 1000, // 限制加载数量
    );

    _isLoading.value = false;
  }

  Future<File> _writeToFile(Uint8List data) async {
    final tempDir = await getTemporaryDirectory();
    final file = File(
      '${tempDir.path}/${DateTime.now().millisecondsSinceEpoch}.jpg',
    );
    await file.writeAsBytes(data);
    return file;
  }

  @override
  void onClose() {
    VideoCompress.dispose();
    super.onClose();
  }
}
